import React, { Component, Fragment } from 'react';
import ReactDOM from 'react-dom';
import { Drag, Drop, DragDropContext, Droppable, Draggable } from './draggable'
import { Pagination, Steps, Card } from 'antd';
const { Step } = Steps;

import 'antd/dist/antd.css';
import './app.css'
// import 'antd/dist/antd.less';


//移除    
const remove = (list = [], startIndex) => {
  const result = Array.from(list);
  result.splice(startIndex, 1);
  return result;
}

// 同一个域中的拖拽交换
const reorder = (list = [], startIndex, endIndex) => {
  const result = Array.from(list);
  const [removed] = result.splice(startIndex, 1);
  result.splice(endIndex, 0, removed);
  return result;
};

// 不同域中的拖拽交换
const move = (source = [], destination = [], droppableSource, droppableDestination) => {
  const sourceClone = Array.from(source);
  const destClone = Array.from(destination);
  const [removed] = sourceClone.splice(droppableSource.index, 1);
  destClone.splice(droppableDestination.index, 0, removed);

  const result = {};
  result[droppableSource.droppableId] = sourceClone;
  result[droppableDestination.droppableId] = destClone;
  return result;
};



//列表排序移动时候拖拽元素的style 和未拖拽的元素的 style
const getItemStyle = (isDragging, draggableStyle) => ({
  userSelect: 'none',
  padding: `20px 0`,
  margin: `0 0 10px 0`,
  background: isDragging ? 'grey' : 'grey',
  ...draggableStyle
})

//当列表有元素被拖拽时候的style和没拖拽时候的style
const getListStyle = isDraggingOver => ({
  background: isDraggingOver ? 'lightblue' : 'lightgrey',
  padding: 10,
  width: 400
})


function functionButtion(data) {
  return <button style={{ marginTop: 10 }}>{data.buttonName}</button>
}

function ComponentForCard(data) {
  return <Card size="small" title="Small size card" extra={<a href="#">More</a>} style={{ width: 300 }}>
    <p>Card content</p>
    <p>Card content</p>
    <p>Card content</p>
  </Card>
}

function ComponentForPagination(data) {
  return <Pagination defaultCurrent={1} total={50} />
}
function ComponentForStep(props) {
  return <Steps current={1}>
    <Step title="Finished" description="This is a description." />
    <Step title="In Progress" subTitle="Left 00:00:08" description="This is a description." />
    <Step title="Waiting" description="This is a description." />
  </Steps>
}




let STATUS_FUNCTION = [
  {
    id: "121212",
    buttonName: "分页器",
    reactNodeRender: functionButtion,
    componentsMapName: "pagination",  //组件映射的名字
    isDragDisabled: false,
    data: { name: "张三", text: "分页器" },
  },
  {
    id: 1,
    buttonName: "步骤器",
    reactNodeRender: functionButtion,
    componentsMapName: "step",  //组件映射的名字
    isDragDisabled: false,
    data: { name: "张三" },
  },
  {
    id: 3,
    buttonName: "卡片",
    reactNodeRender: functionButtion,
    componentsMapName: "card",  //组件映射的名字
    isDragDisabled: false,
    data: { name: "张三" },
  }
]

let STATUS_PRIVIEW = [
  {
    id: 1,
    buttonName: "步骤器",
    reactNodeRender: functionButtion,
    componentsMapName: "step",  //组件映射的名字
    isDragDisabled: false,
    data: { name: "张三" },
  },
]


export default class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      STATUS_PRIVIEW: STATUS_PRIVIEW,
      STATUS_FUNCTION: STATUS_FUNCTION,
    }
  }





  getList = id => this.state[id]

  onDragEnd = result => {
    const { source, destination } = result
    if (!destination) {
      if (source.droppableId === 'STATUS_PRIVIEW') {
        const STATUS_PRIVIEW = remove(
          this.getList(source.droppableId),
          source.index,
          // destination.index
        );
        let state = { STATUS_PRIVIEW };
        this.setState(state);
      }
      return
    }

    if (source.droppableId === destination.droppableId) {
      const items = reorder(
        this.getList(source.droppableId),
        source.index,
        destination.index
      );
      let state = { STATUS_PRIVIEW: items };
      if (source.droppableId === 'STATUS_FUNCTION') {
        state = { STATUS_FUNCTION: items };
      }
      this.setState(state);
    }
    else {
      const result = move(
        this.getList(source.droppableId),
        this.getList(destination.droppableId),
        source,
        destination
      );

      this.setState({
        STATUS_PRIVIEW: result.STATUS_PRIVIEW,
        STATUS_FUNCTION: result.STATUS_FUNCTION
      });
    }
  };

  onDragStart = (id) => {
    this.setState({
      activeId: id
    });
  };

  dragTo = (region, componentType, id) => {
    let { STATUS_PRIVIEW, activeId } = this.state;
    console.log(region, componentType, id, activeId, "++++++++++")
    if (region == "STATUS_PRIVIEW") {
      let find = STATUS_FUNCTION.find((item) => item.id == activeId)
      if (find) {
        // STATUS_PRIVIEW.unshift({ ...find, id: Date.now() })
        STATUS_PRIVIEW.push({ ...find, id: Date.now() })
        this.setState({
          STATUS_PRIVIEW: STATUS_PRIVIEW
        })
      }
    }
    // let task = tasks[activeId];
    // if (task.region !== region) {
    //   task.region = region;
    //   this.setState({
    //     tasks: tasks
    //   });
    // }
    // this.hanleDragEnd();
  };

  hanleDragEnd = () => {
    this.setState({
      activeId: null
    });
  };

  render() {
    const { STATUS_PRIVIEW, STATUS_FUNCTION, activeId } = this.state

    let letFunctionMap = {
      pagination: ComponentForPagination,
      step: ComponentForStep,
      card: ComponentForCard,
    }

    function getNode(statusItem, data) {
      if (statusItem == "STATUS_FUNCTION") {
        return data.reactNodeRender(data)
      } else {
        let Component = letFunctionMap[data.componentsMapName]
        if (Component) {
          return <Component {...data} />
        } else {

        }
        return data.reactNodeRender(data)
      }
    }



    return (
      // export interface DragDropContextProps {
      //     onBeforeCapture?(before: BeforeCapture): void;
      //     onBeforeDragStart?(initial: DragStart): void;
      //     onDragStart?(initial: DragStart, provided: ResponderProvided): void;
      //     onDragUpdate?(initial: DragUpdate, provided: ResponderProvided): void;
      //     onDragEnd(result: DropResult, provided: ResponderProvided): void;
      //     children: React.ReactNodeRender | null;
      //     dragHandleUsageInstructions?: string;
      //     nonce?: string;
      //     enableDefaultSensors?: boolean;
      //     sensors?: Sensor[];
      // }
      <div className="task-wrapper">
        <Drop
          region="STATUS_FUNCTION"
          className="STATUS_FUNCTION"
          dragTo={this.dragTo}
        // canDragIn={activeId !== null && tasks[activeId].region !== region}
        >
          {STATUS_FUNCTION.map((item) => (
            <Drag
              key={item.id}
              active={item.id === activeId}
              id={item.id}
              componentType={item.componentsMapName}
              onDragStart={this.onDragStart}
              onDragEnd={this.hanleDragEnd}
            >
              {getNode("STATUS_FUNCTION", item)}
            </Drag>
          ))}
        </Drop>

        <Drop
          region="STATUS_PRIVIEW"
          className="STATUS_PRIVIEW"
          dragTo={this.dragTo}
        // canDragIn={activeId !== null && tasks[activeId].region !== region}
        // canDragIn={true}
        >
          {/* {STATUS_PRIVIEW.map((item) => (
            <Drag
              key={item.id}
              active={item.id === activeId}
              id={item.id}
              title={item.title}
              point={item.point}
              username={item.username}
              isDragDisabled={true}
              onDragStart={this.onDragStart}
              onDragEnd={this.hanleDragEnd}
            >
              {getNode("STATUS_PRIVIEW", item)}
            </Drag>
          ))} */}


          <DragDropContext onDragEnd={this.onDragEnd} >
            <Droppable
              droppableId="STATUS_PRIVIEW"
            // type="person"
            // direction="horizontal"
            >
              {(provided, snapshot) => (
                <div
                  ref={provided.innerRef}
                  style={getListStyle(snapshot.isDraggingOver)}>
                  {STATUS_PRIVIEW.map((item, index) => (
                    <Draggable
                      key={item.id}
                      draggableId={item.id}
                      // isDragDisabled={true}
                      index={index}>
                      {(provided, snapshot) => (
                        <div
                          ref={provided.innerRef}
                          {...provided.draggableProps}
                          {...provided.dragHandleProps}
                          style={getItemStyle(
                            snapshot.isDragging,
                            provided.draggableProps.style
                          )}>
                          {getNode("STATUS_PRIVIEW", item)}
                        </div>
                      )}
                    </Draggable>
                  ))}
                  {provided.placeholder}
                </div>
              )}
            </Droppable>

            {/* <Droppable droppableId="STATUS_FUNCTION" >
            {(provided, snapshot) => (
              <div
                ref={provided.innerRef}
                style={getListStyle(snapshot.isDraggingOver)}>
                {STATUS_FUNCTION.map((item, index) => (
                  <Draggable
                    key={item.id + index}
                    draggableId={item.id}
                    index={index}>
                    {(provided, snapshot) => (
                      <div
                        ref={provided.innerRef}
                        {...provided.draggableProps}
                        {...provided.dragHandleProps}
                        style={getItemStyle(
                          snapshot.isDragging,
                          provided.draggableProps.style
                        )}>
                        {getNode("STATUS_FUNCTION", item)}
                      </div>
                    )}
                  </Draggable>
                ))}
                {provided.placeholder}
              </div>
            )}
          </Droppable> */}
          </DragDropContext>
        </Drop>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
